package pers.cz.javacvdemo.video;

import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;

import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @version 1.0
 * @description:
 * @author: ChengZhi 0336
 * @create: 2025-08-12 17:22
 **/
@Slf4j
public class VideoResolutionTransform {

	public void execTransform(List<FFmpegFrameRecorder> recorders, Path tempFile) {

		CountDownLatch latch = new CountDownLatch(recorders.size());
		AtomicInteger successCount = new AtomicInteger(0);
		AtomicLong totalFrames = new AtomicLong(0);

		log.info("开始转换共{}个分辨率...", recorders.size());
		recorders.forEach(recorder -> {
			CustomerThreadPool.execute(() -> {
				FFmpegFrameGrabber grabber = null;
				try {
					grabber = createGrabber(tempFile);

					// 启动录制
					recorder.start();

					// 转换视频
					int frameCount = convertFrames(grabber, recorder);

					// 停止录制
					recorder.stop();
					recorder.release();

					totalFrames.addAndGet(frameCount);
					successCount.incrementAndGet();
					log.info("转换完成，成功转换 {} 个分辨率", successCount.get());
				} catch (Exception e) {
					log.error("转码失败！");
				} finally {
					cleanup(grabber);
					latch.countDown();
				}
			});
		});

		try {
			// 等待所有任务完成
			latch.await();
		} catch (InterruptedException e) {
			log.error("等待任务完成时被中断!", e);
			Thread.currentThread().interrupt();
		}
	}

	private FFmpegFrameGrabber createGrabber(Path tempFile) throws Exception {
		FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(tempFile.toString());
		grabber.start();
		return grabber;
	}

	private int convertFrames(FFmpegFrameGrabber grabber, FFmpegFrameRecorder recorder) throws Exception {
		Frame frame;
		int frameCount = 0;
		long startTime = System.currentTimeMillis();

		while ((frame = grabber.grab()) != null) {
			recorder.record(frame);
			frameCount++;

			// 显示进度
			if (frameCount % 300 == 0) {
				long currentTime = System.currentTimeMillis();
				double elapsed = (currentTime - startTime) / 1000.0;
				log.info("已处理 {} 帧，耗时 {} 秒", frameCount, elapsed);
			}
		}

		return frameCount;
	}

	private boolean isValidFrame(Frame frame) {
		return frame != null &&
				frame.image != null &&
				frame.imageWidth > 0 &&
				frame.imageHeight > 0;
	}

	private void cleanup(FFmpegFrameGrabber grabber) {
		if (grabber != null) {
			try {
				grabber.stop();
				grabber.release();
			} catch (Exception e) {
				System.err.println("清理grabber失败: " + e.getMessage());
			}
		}
	}
}
